Guild icon
Project Sekai
🔒 UMDCTF 2023 / ✅-crypto-lets-catch-up
Avatar
Let's catch up! - 500 points
Category: Crypto Description: I should probably catch up with my buddy Alice on some important matters. It feels like ages since we last caught up. Only problem is, I seem to have misplaced my encryption key. https://lets-catch-up.chall.lol/ Files: No files. Tags: No tags.
Sutx pinned a message to this channel. 04/28/2023 7:59 PM
Avatar
@unpickled admin bot wants to collaborate 🤝
Avatar
this looks like a reverse
Avatar
unpickled admin bot 04/28/2023 8:29 PM
yep i looked at the js and i closed the website
Avatar
yeah lmao
20:29
gonna do others before coming back
Avatar
unpickled admin bot 04/28/2023 8:29 PM
im still kinda afk so sry bout that
Avatar
yeah np
20:30
hw >> ctf lmao
Avatar
@fleming wants to collaborate 🤝
Avatar
@Violin wants to collaborate 🤝
Avatar
@Utaha wants to collaborate 🤝
Avatar
ok maybe ill look at it a bit
09:48
will first deobfuscate that stuff
09:53
wait
09:54
i found the source code i think
09:55
lmao
09:55
now i can replace everything and compare
09:55
yeah exactly the same, so author copied and renamed
09:55
thats prob step 1 the osint
09:56
crypto lib
10:03
actually no need to replace
10:03
the code is just
10:07
https://github.com/ethers-io/ethers-cli/blob/master/static/index.html#L462 Line 462 till Line 1257 Where e -> encrypt d -> decrypt
10:07
lmao so this is JUST aesjs lib
10:08
i didnt compare hard, but they seem just replacing printed logs (from actual msg to "bruh moment") then renamed variables
10:09
so now i copied it locally and gonna replace code to see if output is the same
10:12
M: { eb: 𐼂𐼅𐼆𐼉𐼀𐼁, cb: 𐼇𐼀𐼃𐼉𐼉𐼀, cf: 𐼁𐼁𐼀𐼆𐼁𐼉, of: 𐼇𐼄𐼁𐼄𐼁𐼃, ct: 𐼄𐼃𐼅𐼇𐼁𐼂𐼉 }, where ours is ModeOfOperation: { ecb: ModeOfOperationECB, cbc: ModeOfOperationCBC, cfb: ModeOfOperationCFB, ofb: ModeOfOperationOFB, ctr: ModeOfOperationCTR },
10:15
lol ok they probably changed sth, replacing gives different hex value
Avatar
so i guess they modified aes.js a bit and we need to find out whats changed in AES
10:26
maybe constants
10:40
i got a hit
10:40
so i know whats the difference now
10:41
yeah rest are the same
10:45
const content = document.getElementById("content").value; const bytes = aesjs.utils.utf8.toBytes(content); const k = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32]; const i = [21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36]; var ac = new aesjs.ModeOfOperation.cbc(k, i); var eB = ac.encrypt(bytes); var eH = aesjs.utils.hex.fromBytes(eB); var eB = aesjs.utils.hex.toBytes(eH); var ac = new aesjs.ModeOfOperation.cbc([...document.getElementById('flag').value].map(c => parseInt(c.charCodeAt(0))), i); var dB = ac.decrypt(eB); var dT = aesjs.utils.utf8.fromBytes(dB); if(dT === document.getElementById("content").value) { tldr, document.getElementById("content").value is some long text, the code first encrypts it using CBC (it is not exactly the same as aesjs lib, 1 minor change). Then it tries to take the flag input and decrypt, we need to get same result The only change from aesjs: in AES.prototype._prepare, normally it ends like screenshot show, but instead their code hard-coded the encryption round keys _Ke to something different in the end: // inverse-cipher-ify the decryption round key (fips-197 section 5.3) for (var r = 1; r < rounds; r++) { for (var c = 0; c < 4; c++) { tt = this._Kd[r][c]; this._Kd[r][c] = (U1[(tt >> 24) & 0xFF] ^ U2[(tt >> 16) & 0xFF] ^ U3[(tt >> 8) & 0xFF] ^ U4[ tt & 0xFF]); } } this._Ke = [[1431127107, 1413905273, 880369457, 1601003876], [...]]; //HARDCODED
10:46
this makes encrypted result different (i think?), but idk if decryption uses this _Ke
10:46
I am able to get eB
10:46
goal is to recover ac's key
10:47
does anyone know how it works
10:48
yeah _Ke only used in encryption
10:49
So basically we encrypted text XXX to some other ciphertext (because of wrong Ke) and we want to find decryption key that decrypts it back to XXX with regular aes cbc Kd (edited)
10:49
i hate aes lol
10:50
ah wait
10:52
yeah idk, i think i reversed everything already, just AES step left which idk
10:52
if anyone knows aes stuff can continue
10:52
i have all data
Avatar
sorry what's the goal here
Avatar
by the way you can go browser and type this in console to get values (edited)
11:30
breakpoint here
11:34
20.06 KB
11:34
@Utaha
11:34
only this changed from standard aesjs copied online
11:36
so if i input "a"*16, local data and remote match (which i think it means my impl is correct)
Avatar
If I can find a key that produce the same Ke as the hardcoded one, does that solve the chall?
Avatar
what does this mean?
12:38
if you input the key in the challenge website it should show green
12:40
from what i see there's no remote - its basically a local challenge and all checks are done locally
12:40
The thing input in "key: " box is flag
Avatar
I mean it's really unlikely that AESDecrypt(flag, Enc(k, text)) = text
13:12
unless Enc is actually the same as AES encrypt
Avatar
yeah
13:13
i see
13:13
yes i think so
Avatar
but that Ek calculation is really messy
Avatar
if the key produces the same Ke then dec(enc) is just the plain text
Avatar
lol the first round key is literally the first 16 bytes of the flag
Avatar
lol what
Avatar
UMDCTF{y4y_1_mad
13:21
I was just checking Ke algo
13:22
they transform the key to several 32 bit integers
13:22
and put it in the very first round key
13:23
e_some_new_k3y5}
13:23
hmm 32 bytes key
13:23
yeah got it
13:23
so stupid
Avatar
yeah 3 2bytes
13:23
yeah
Avatar
Avatar
Utaha
used /ctf solve
✅ Challenge solved.
Avatar
lmao
13:23
so just checking Ke algo?
13:23
nothing else needed
13:24
13:24
Those two arrays are just the first 2 elements in Ke
Avatar
LMAO
13:24
ok
13:24
stupid lol
Avatar
referring this
13:25
// convert the key into ints var tk = convertToInt32(this.key); // copy values into round key arrays var index; for (var i = 0; i < KC; i++) { index = i >> 2; this._Ke[index][i % 4] = tk[i]; this._Kd[rounds - index][i % 4] = tk[i]; }
Avatar
ah yeah
13:25
lol, wasted some time on deobfuscating it
Avatar
i did remember that having round keys immediately gives you the actual key, but just forgot the details lol
Avatar
osint chall
13:26
😆
Exported 97 message(s)